#-----------------------------
# ~ tmux.conf ~ for Chris Jones
# github / @ipatch
# twitter / @truckmonth
#- 

#-----------------------------
# NOTE: `display` is short for `display-message`
# NOTE: `bind` is short for `bind-key`
# NOTE: `-n` flag prefix not required key-binding
# NOTE: `set-option` controls the look / feel of tmux.
# NOTE: official tmux documentation, 
#       ... https://github.com/tmux/tmux/wiki/FAQ 
#       ....uses double quotes and not single.
# 
# TODOs: ipatch
# - [ ] experiment with launching the new window after the current window in the stack,
# ...ie. don't put new window as the last window in the session
# - [x] print the current value of a setting?
    # `tmux show-options -g set-clipboard`
#-

# remove all previous bindings, useful when exp with new bindings,
# and old ones aren't removed, see: https://unix.stackexchange.com/a/57648/33002
# NOTE: i get mixed results with below binding
# unbind-key -a

# NOTE: tmux default "prefix" key is `C-b` ie. <Control>+b 🤸
unbind C-b

# NOTE: `-g` flag makes the "prefix" global to ALL tmux sessions.
# reassign the "prefix" key.
set -g prefix C-s

bind r source-file ~/.tmux.conf \; display "~/.tmux.conf reloaded"

# NOTE: requires tmux >= 3.2
# NOTE: raspbian (apr 19 2023) does not ship tmux v3.2
if-shell -b "[[ $(tmux -V | cut -d' ' -f2) > '3.2' ]]" "set-option extended-keys on"

# Neovim recommended "escape" time setting
set -sg escape-time 10

# use custom compiled terminfo file
set -g default-terminal "tmux-256color"

# enable 24 bit color, ie. true color
set-option -sa terminal-overrides ",xterm*:Tc"

# NOTE: setting this to `fish` solves my issues related to out of order $PATH entries
# REF: https://unix.stackexchange.com/a/548516/33002
# NOTE: TODO: below setting is problematic when the fish shell is not installed
# set-option -g default-command fish

## nova's
# set -ga terminal-overrides ",screen-256color:Tc"
# set -as terminal-overrides ',xterm*:Tc:sitm=\E[3m'

# Experimental
set-window-option -g xterm-keys on

#-----------------------------
# STYLES / STYLING / status line / bar
# NOTE: to print options that can be styled `tmux show -g`
##
# NOTE: `set` is short for `set-option`, it is an internal alias within tmux.
# set -g utf8 on #INVALID, nova
set -g status-position top
set -g status-bg "#3e93b2"
set -g status-fg "#01070a"

# center the window list in status line
set -g status-justify centre 

# NOTE: display session name up to 50 characters long in the lower left of the tmux status bar.
set -g status-left-length 50

# modify the default left status bar, rm `[]`
set -g status-left "#S #{?client_prefix,#[fg=colour208]^S,}" 

# NOTE: ipatch, rm battery line, and date from right prompt, i3 polybar displays those
set -g status-right " #[fg=colour000]"

# styles for windows
## styles for current active window
### TODO: see repo README, for style window titles to fit zoom icon into empty space
### ...presently zoom icon appends to window name, thus moving layout of all text in status bar ...BOO!
setw -g window-status-current-format "#[fg=#000000]#[bg=colour208]#I:#W#{?window_zoomed_flag,🔍,}#{?pane_synchronized,🏊🏊,}"
## styles for inactive windows, ie. background windows
setw -g window-status-format "#I:#W#{?window_zoomed_flag,🔍,}#{?pane_synchronized,🏊🏊,}"

#----------------------------
# STYLES / STYLING / panes
#- NOTE: may be deprecated in tmux ≥ 2.9
#--------------
# borders
# set-option -g pane-active-border-bg default
# set-option -g pane-active-border-fg colour208 # an orangish unbuntu color

#-----------------------------
# History
# NOTE: to remove scroll back history within a tmux pane `prefix + ctrl+k`
#-
bind C-l send-keys "C-l" # `prefix + C-l` to clear the screen
bind C-k send-keys -R \; send-keys "C-l" \; clear-history
set -g history-limit 200000    # Scrollback for weeks (default is 2000)

# toggle pane syncronization
bind e setw synchronize-panes

#-----------------------------
# Winow / pane splitting
#-
# TODO: tmux requires adding single quotes around `-` and `\` whereas prior versions did not
# ...time permitting conditionally change settings based tmux version if not backward compatible

# split pane and preserve path

bind '-' split-window -v -c "#{pane_current_path}" 
bind '\' split-window -h -c "#{pane_current_path}" 

# exp, get pane from different window and put within the current window
# TODO: provide example of how cmd works
bind-key @ command-prompt -p "create pane from:"  "join-pane -s ':%%'"

#-----------------------------
# NOTE: `setw` is short for `set-window-option`
#-

# begin window numbering at 1 instead of 0
setw -g base-index 1 

setw -g renumber-windows on

# Vim style navigation in copy mode
setw -g mode-keys vi 

set -g default-shell $SHELL
set -g mouse on

#-----------------------------
# tmux / bindings / window management
#-
# new window preserve path
bind -n M-t new-window -c "#{pane_current_path}" 

# move active window to the left, and keep it active for faster relocation
bind -n S-C-left  swap-window -t -1 \; select-window -t -1

# move window to the left
bind-key h swap-window -t :- 

# switch to previous window
bind-key l last-window 

#-----------------------------
# seemless integration between vim & tmux keybindings
#-
# Smart pane switching with awareness of Vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator

# See: https://github.com/christoomey/vim-tmux-navigator/issues/218#issuecomment-495002332
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|vim|nvim|ssh|mosh|tmux?)(diff)?$'"

bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h'  'select-pane -L'
bind-key -n 'C-j' if-shell "$is_vim" 'send-keys C-j'  'select-pane -D'
bind-key -n 'C-k' if-shell "$is_vim" 'send-keys C-k'  'select-pane -U'
bind-key -n 'C-l' if-shell "$is_vim" 'send-keys C-l'  'select-pane -R'

tmux_version='$(tmux -V | sed -En "s/^tmux ([0-9]+(.[0-9]+)?).*/\1/p")'

if-shell -b '[ "$(echo "$tmux_version < 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\'  'select-pane -l'"
if-shell -b '[ "$(echo "$tmux_version >= 3.0" | bc)" = 1 ]' \
    "bind-key -n 'C-\\' if-shell \"$is_vim\" 'send-keys C-\\\\'  'select-pane -l'"

bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
# bind-key -T copy-mode-vi 'C-\' select-pane -l 

#------------------------------
#- smart pane switching 
#- NOTE:  🔥 below key mappings are req'd for switching between panes when using ssh
#--
bind-key -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(vim|emacs)' && tmux send-keys C-h) || tmux select-pane -L"
bind-key -n C-j run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(vim|emacs)' && tmux send-keys C-j) || tmux select-pane -D"
bind-key -n C-k run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(vim|emacs)' && tmux send-keys C-k) || tmux select-pane -U"
bind-key -n C-l run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(vim|emacs)' && tmux send-keys C-l) || tmux select-pane -R"

#-----------------------------
# TERM adapting tmux to work with term title bars
#-

# set-titles-string
set -g set-titles on 

set -g set-titles-string "#{session_name} - #T"

# rename window or pane to current job or process.
# NOTE: doesn't play nice with `Terminal.app`
set -g automatic-rename on

# highlight windows that have unseen activity
set -g monitor-activity on 

# NO notification for activity in a window
set -g visual-activity off 

#-----------------------------
# Logging
#-
bind P pipe-pane -o "cat >>~/logs/#W.tmux.log" \; display "Toggled logging to ~/logs/#W.tmux.log"

#-----------------------------
# binding / double tap, doubletap left shift
#-
# NOTE: below option requires `-g` flag
# NOTE: i believe this broke when tmux was upgraded to 3.2a 
# TODO: fix broken double tap
set-option -g prefix2 "C-S-M-f1" # WORK!!!
bind-key C-S-M-f1 resize-pane -Z # toggle min/max pane in window, prefix not required
# double tap left shift relies on ke for macos

#-----------------------------
# tmux 1.9+ SEE: `man tmux` for more info
#- 
set-option -g focus-events on

#-----------------------------
# tmux / DANGER ZONE!!! ✈ / place to break current tmux config, and store experimental features
#-

#-----------------------------
# macos specific file contents
#-
#-----------------------------
# `reattach-to-user-namespace` macos specific
# NOTE: reattach-to-user-namespace is not required for tmux ≥ 2.6
# TODO: is possible, conditionally load if tmux ≥ 2.6
#-
if-shell "uname | grep -qi linux" "source-file ~/.tmux/tmux.macos.conf"

# bind-key -T copy-mode-vi WheelUpPane send -X scroll-up
# bind-key -T copy-mode-vi WheelDownPane send -X scroll-down
#
# # NOTE: the below settings will only work within tmux >= 2.6
#
# # Vi copy on selction
# setw -g mode-keys vi
# bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy"
# bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "reattach-to-user-namespace pbcopy" \; display-message "Copied to system clipboard"
#-----------------------------

set -s set-clipboard on

#-----------------------------
# blog post https://thevaluable.dev/tmux-config-mouseless/
#-
# unbind -T copy-mode-vi Space; #Default for begin-selection
# unbind -T copy-mode-vi Enter; #Default for copy-selection
#
# bind -T copy-mode-vi v send-keys -X begin-selection
# bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xsel --clipboard"
#-

# exp with shared clipboard local/remote & nested tmux
yank="~/.tmux/yank.sh"
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "$yank"

# unbind-key Enter
# unbind-key MouseDragEnd1Pane

# NOTE: https://github.com/tmux/tmux/wiki/FAQ#i-want-to-use-the-mouse-to-select-panes-but-the-terminal-to-copy-how
unbind -Troot MouseDragEnd1Pane

# bind-key -T copy-mode-vi MouseDragEnd1Pane send -X copy-pipe "xclip -selection clipboard -i" \; send -X clear-selection

# NOTE: list available tmux commands
# `:list-commands`
# exampels:
# `:move-pane`
# `:resize-pane`

#-----------------------------
# tmux / DANGER ZONE!!!! / EXP WITH NESTING TMUX SESSIONS!
# ref: https://asciinema.org/a/287924
#-

# attempt to unbind `C-S-l` and C-S-h`
unbind-key -n C-S-l
unbind-key -n C-S-h

# key mapping / move current window to the right
# TODO: after moving the window position, focus on the moved window

# NOTE: the below bindings / mappings NO WORK!
bind -n C-S-l swap-window -s +1
bind -n C-S-h  swap-window -s -1

# - [x] Q: what is `set-hook` and `set-environment` 
          # A: man tmux

set-hook -g session-created { set-environment nested_level 0 }

bind-key -n F12 display "F12 press pressed" 

# TODO: ipatch, where to find info on `bind` cmd and `-T` flag
# NOTE: ipatch, `-T` flag = sets the key table, useful with cmd `list-keys`

# NOTE: define tmux var based on value of envvar
# `set-option -g my_var "#{env:MY_VARIABLE}"`

# define custom colors
# NOTE: to print value of var from shell
# `tmux showenv -g MYCOLOR`
MYCOLOR="#00ffff"
CUSTOM_CYBERPUNK="#8f8ce3"
IPATCH_GREY="#999999"
STAR_WARS_CREDITS_BLUE="#3e93b2"

# TODO: ipatch, what do the `qg` flags do?

# unbind-key -n F11
# bind -n F11 set -ga status-bg $CUSTOM_CYBERPUNK
bind -n F11 set -ga status-bg $IPATCH_GREY

# NOTE: ipatch, top tmux status bar, reverse binding to move into inner tmux seesion
# NOTE: pressing `prefix` is not req for below binding

bind -T root S-down {
# set the inactive status bar to grey moving into nested sesh
  set -ga status-bg $IPATCH_GREY
  set-environment nested_level 1
  set prefix None
  set key-table off
  # set-option window-status-current-style "bg=green"
  # set-option window-status-current-style "fg=green,bg=black"
  if-shell -F '#{pane_in_mode}' { send-keys -X cancel }
  refresh-client -S
}

# unbind-key -n S-down
bind -T off S-up {
  set -u prefix
  set -u key-table
  refresh-client -S
  set -ga status-bg $STAR_WARS_CREDITS_BLUE
}

#-----------------------------
# tmux / plugins
# NOTE: for plugin removal, uninstall
# ... https://github.com/tmux-plugins/tpm/blob/master/docs/managing_plugins_via_cmd_line.md
#-
set -g @plugin "tmux-plugins/tpm"
set -g @plugin "tmux-plugins/tmux-resurrect"
# set -g @plugin "rcribbs/tmux-fzf-session-switch"

#-----------------------------
# tmux / plugin / tmux-resurrect
#-
set -g @resurrect-processes 'ssh psql mysql sqlite3 fish'
set -g @resurrect-strategy-nvim 'session'

# Initialize TMUX plugin manager 
# 🚨 ALERT: 👇 must be last line in `tmux.conf`
run "~/.tmux/plugins/tpm/tpm"
